package cn.tedu.kcircle.security.support.filter;

import cn.tedu.kcircle.common.consts.HttpConst;
import cn.tedu.kcircle.common.po.CurrentPrincipal;
import cn.tedu.kcircle.passport.api.rpc.PassportRpcApi;
import cn.tedu.kcircle.passport.protocol.dto.UserInfoDTO;
import com.alibaba.fastjson.JSON;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;
import java.util.List;

@Slf4j
@AllArgsConstructor
public class JwtAuthorizationFilter extends OncePerRequestFilter implements HttpConst {
    private PassportRpcApi passportRpcApi;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String userIdStr = request.getHeader(HEADER_USER_ID);
        String userAddr = request.getHeader(HEADER_USER_ADDR);
        String userAgent = request.getHeader(HEADER_USER_AGENT);
        if (userIdStr != null) {
            long userId = Long.parseLong(userIdStr);
            UserInfoDTO loginInfo = passportRpcApi.getLoginInfo(userId);
            if (loginInfo != null) {
                CurrentPrincipal principal = new CurrentPrincipal().setUserId(userId).setUserAddr(userAddr).setUserAgent(userAgent).setUsername(loginInfo.getUsername());
                List<String> permission = JSON.parseArray(loginInfo.getAuthorityJsonString(), String.class);
                List<SimpleGrantedAuthority> authorities = permission != null ? permission.stream().map(SimpleGrantedAuthority::new).toList() : null;
                Authentication authentication = new UsernamePasswordAuthenticationToken(principal, new Object(), authorities);
                SecurityContext securityContext = SecurityContextHolder.getContext();
                securityContext.setAuthentication(authentication);
            }
        }
        filterChain.doFilter(request, response);
    }
}
